<?php
class PHZ_CanHu
{

    public static $canHu      = false;
    public static $limit_huxi = 6;//最低起息，6胡
    public static $huXi       = 0;
    public static $temp_log_card = array();
    public static $is_1510    = true;//是否打1.5.10

    public static function __canLog( $log ){
        //....胡牌日志
    }

    /**
     * @param $huxi               默认胡息（指已存在下牌区域中的胡息数）
     * @param $card               手牌数组格式，0-20 （共21个单位；其中0的下标没有值）
     * @param $length             手牌中牌数量的总计
     * @param $zimoPaiValue       是否自摸牌（自己自摸为牌号，他人打出为-1）
     * @param $jiangs             将的数量（只有提或者跑才会出现将）- 默认为0
     */
    public static function __CanHu( $huxi , $card , $length , $zimoPaiValue , $jiangs ){
        //设置初始化huXi
        self::$huXi  = $huxi;
        //如果将的数量大于等于2，则不能胡
        if( count($jiangs) > 1 ){return false;}
        //如果所有牌被递归完，且胡息不能满足最低跟将不是小于等于1的情况下，不能胡
        if( $length == 0 ){
            if( $huxi >= self::$limit_huxi && count( $jiangs ) <= 1 ){
                self::__canLog("长度=0，胡息:" . $huxi . ",将数：" . count( $jiangs ) );
                self::$canHu = true;
                return true;
            }else{
                return false;
            }
        }
        //大字坎（6胡息） - 自摸
        for( $i = 11 ; $i <= 20 ; $i++ ){
            //如果
            if( $zimoPaiValue == $i && $card[$i] == 3 ){
                $card[$i] -= 3;
                $huxi += 6;
                self::$huXi += 6;
                if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                    self::__canLog("找到大字坎（自摸）：" . self::$temp_log_card[$i] );
                    self::$canHu = true;
                    return true;
                }else{
                    $huxi -=6;$card[$i] += 3;self::$huXi -= 6;
                }
            }
        }
        //大字碰胡 3 胡息
        for( $i = 11 ; $i <= 20 ; $i++ ){
            //如果
            if( $zimoPaiValue != $i && $card[$i] == 3 ){
                $card[$i] -= 3;
                $huxi += 3;
                self::$huXi += 3;
                if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                    self::__canLog("找到大字坎（碰胡）：" . self::$temp_log_card[$i] );
                    self::$canHu = true;
                    return true;
                }else{
                    $huxi -=3;$card[$i] += 3;self::$huXi -= 3;
                }
            }
        }
        //大字2.7.10
        if( $card[12] > 0 && $card[17] > 0 && $card[20] > 0 ){
            $card[12] -= 1 ;$card[17] -= 1 ;$card[20] -= 1 ;$huxi+= 6;
            self::$huXi += 6;
            if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                self::__canLog("找到大字牌（2.7.10）：" . self::$temp_log_card[12] . "-" . self::$temp_log_card[17] . "-" . self::$temp_log_card[20] );
                self::$canHu = true;
                return true;
            }else{
                $card[12] += 1 ;
                $card[17] += 1 ;
                $card[20] += 1 ;
                $huxi -= 6;
                self::$huXi -= 6;
            }
        }
        //大字1.2.3
        if( $card[11] > 0 && $card[12] > 0 && $card[13] > 0 ){
            $card[11] -= 1 ;$card[12] -= 1 ;$card[13] -= 1 ;$huxi+= 6;
            self::$huXi += 6;
            if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                self::__canLog("找到大字牌（1.2.3）：" . self::$temp_log_card[11] . "-" . self::$temp_log_card[12] . "-" . self::$temp_log_card[13] );
                self::$canHu = true;
                return true;
            }else{
                $card[11] += 1 ;
                $card[12] += 1 ;
                $card[13] += 1 ;
                $huxi -= 6;
                self::$huXi -= 6;
            }
        }
        //大字1.5.10 - 打的情况下才有
        if( self::$is_1510 == true ) {
            if ($card[11] > 0 && $card[15] > 0 && $card[20] > 0) {
                $card[11] -= 1;
                $card[15] -= 1;
                $card[20] -= 1;
                $huxi += 6;
                self::$huXi += 6;
                if (self::__CanHu($huxi, $card, $length - 3, $zimoPaiValue, $jiangs) == true) {
                    self::__canLog("找到大字牌（1.5.10）：" . self::$temp_log_card[11] . "-" . self::$temp_log_card[15] . "-" . self::$temp_log_card[20]);
                    self::$canHu = true;
                    return true;
                } else {
                    $card[11] += 1;
                    $card[15] += 1;
                    $card[20] += 1;
                    $huxi -= 6;
                    self::$huXi -= 6;
                }
            }
        }
        /***************************************************************************************************************/
        //小字坎（3胡息） - 自摸
        for( $i = 1 ; $i <= 10 ; $i++ ){
            //如果
            if( $zimoPaiValue == $i && $card[$i] == 3 ){
                $card[$i] -= 3;
                $huxi += 3;
                self::$huXi += 3;
                if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                    self::__canLog("找到小字坎（自摸）：" . self::$temp_log_card[$i] );
                    self::$canHu = true;
                    return true;
                }else{
                    $huxi -=3;$card[$i] += 3;self::$huXi -= 3;
                }
            }
        }
        //小字碰胡 1 胡息
        for( $i = 1 ; $i <= 10 ; $i++ ){
            //如果
            if( $zimoPaiValue != $i && $card[$i] == 3 ){
                $card[$i] -= 3;
                $huxi += 1;
                self::$huXi += 1;
                if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                    self::__canLog("找到小字坎（碰胡）：" . self::$temp_log_card[$i] );
                    self::$canHu = true;
                    return true;
                }else{
                    $huxi -=1;$card[$i] += 3;self::$huXi -= 1;
                }
            }
        }
        //小字2.7.10
        if( $card[2] > 0 && $card[7] > 0 && $card[10] > 0 ){
            $card[2] -= 1 ;$card[7] -= 1 ;$card[10] -= 1 ;$huxi+= 3;
            self::$huXi += 3;
            if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                self::__canLog("找到小字牌（2.7.10）：" . self::$temp_log_card[2] . "-" . self::$temp_log_card[7] . "-" . self::$temp_log_card[10] );
                self::$canHu = true;
                return true;
            }else{
                $card[2] += 1 ;
                $card[7] += 1 ;
                $card[10] += 1 ;
                $huxi -= 3;
                self::$huXi -= 3;
            }
        }
        //小字1.2.3
        if( $card[1] > 0 && $card[2] > 0 && $card[3] > 0 ){
            $card[1] -= 1 ;$card[2] -= 1 ;$card[3] -= 1 ;$huxi+= 3;
            self::$huXi += 3;
            if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                self::__canLog("找到小字牌（1.2.3）：" . self::$temp_log_card[1] . "-" . self::$temp_log_card[2] . "-" . self::$temp_log_card[3] );
                self::$canHu = true;
                return true;
            }else{
                $card[1] += 1 ;
                $card[2] += 1 ;
                $card[3] += 1 ;
                $huxi -= 3;
                self::$huXi -= 3;
            }
        }
        //小字1.5.10 - 打的时候才有
        if( self::$is_1510 == true ) {
            if ($card[1] > 0 && $card[5] > 0 && $card[10] > 0) {
                $card[1] -= 1;
                $card[5] -= 1;
                $card[10] -= 1;
                $huxi += 3;
                self::$huXi += 3;
                if (self::__CanHu($huxi, $card, $length - 3, $zimoPaiValue, $jiangs) == true) {
                    self::__canLog("找到小字牌（1.5.10）：" . self::$temp_log_card[1] . "-" . self::$temp_log_card[5] . "-" . self::$temp_log_card[10]);
                    self::$canHu = true;
                    return true;
                } else {
                    $card[1] += 1;
                    $card[5] += 1;
                    $card[10] += 1;
                    $huxi -= 3;
                    self::$huXi -= 3;
                }
            }
        }
        /***************************************************************************************************************/
        //小字一句话
        for( $i = 1 ; $i <= 8 ; $i++ ){
            if( $card[$i] > 0 && $card[$i+1] > 0 && $card[$i+2] > 0 ){
                $card[$i]   -= 1;
                $card[$i+1] -= 1;
                $card[$i+2] -= 1;
                if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                    self::__canLog("找到小字一句话：" . $i . "-" . ($i+1) . "-" . ($i+2) );
                    self::$canHu = true;
                    return true;
                }else{
                    $card[$i]   += 1;
                    $card[$i+1] += 1;
                    $card[$i+2] += 1;
                }
            }
        }
        //大字一句话
        for( $i = 11 ; $i <= 18 ; $i++ ){
            if( @$card[$i] > 0 && @$card[$i+1] > 0 && @$card[$i+2] > 0 ){
                $card[$i]   -= 1;
                $card[$i+1] -= 1;
                $card[$i+2] -= 1;
                if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                    self::__canLog("找到大字一句话：" . $i . "-" . ($i+1) . "-" . ($i+2) );
                    self::$canHu = true;
                    return true;
                }else{
                    $card[$i]   += 1;
                    $card[$i+1] += 1;
                    $card[$i+2] += 1;
                }
            }
        }
        /***************************************************************************************************************/
        //是否有姣牌
        for( $i = 1 ; $i <= 10 ; $i++ ){
            if( $card[$i] > 0 && $card[ (10+$i) ] >= 2 ){
                $card[$i] -= 1;$card[ (10+$i) ] -= 2;
                if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                    self::__canLog("找到小大大的绞牌：" . self::$temp_log_card[$i] . "-" . self::$temp_log_card[ (10+$i) ] . "-" . self::$temp_log_card[ (10+$i) ] );
                    self::$canHu =  true;
                    return true;
                }else{
                    $card[$i] += 1;$card[ (10+$i) ] += 2;
                }
            }else if( $card[$i] >= 2 && $card[ (10+$i) ] > 0 ){
                $card[$i] -= 2;$card[ (10+$i) ] -= 1;
                if( self::__CanHu( $huxi , $card , $length-3 , $zimoPaiValue , $jiangs ) == true ){
                    self::__canLog("找到小小大的绞牌：" . self::$temp_log_card[$i] . "-" . self::$temp_log_card[$i] . "-" . self::$temp_log_card[ (10+$i) ] );
                    self::$canHu =  true;
                    return true;
                }else{
                    $card[$i] += 2;$card[ (10+$i) ] += 1;
                }
            }
        }
        /***************************************************************************************************************/
        //找对子（将）
        for( $i = 1 ; $i <= 20 ; $i++ ){
            if( $card[$i] >= 2 ){
                $card[$i] -= 2;
                array_push( $jiangs , $i );
                if( self::__CanHu( $huxi , $card , $length - 2 , $zimoPaiValue , $jiangs ) == true ){
                    self::__canLog("找到将，将名：" . self::$temp_log_card[$i] );
                    self::$canHu =  true;
                    return true;
                }else{
                    $new_jiangs  = array();
                    $continues   = 0;
                    foreach ( $jiangs as $key => $value ){
                        if( $value == $i && $continues <= 0 ){
                            $continues++;
                            continue;
                        }
                        array_push( $new_jiangs , $value );
                    }
                    $jiangs = $new_jiangs;
                    $card[$i] += 2;
                }
            }
        }
        //所有都遍历完成还没有返回true，那么这里就返回false
        return false;
    }

    /**
     * 进行数据切割并传入到是否能胡牌的函数当中
     * @param $huxi                  下牌中已经存在的息数  +  手中三个坎字的息数
     * @param $card_string           手牌
     * @param $card_number           代入手牌中的牌
     * @param $isZiMoOrCardNumber    自摸的牌的时候，这个值 = card_number，  别人打出来或者摸出来的牌；这里是-1
     * @param $room_info             房间信息
     */
    public static function __isCan_Hu_Pai( $huxi , $card_string , $card_number , $isZiMoOrCardNumber , $room_info ){
        $card_array  = explode(",", $card_string );
        $card_huxi   = array();
        for( $i = 0 ; $i <= 20 ; $i++ ){
            if( $i == $card_number ){
                $card_huxi[$i] = 0;
            }else {
                $card_huxi[$i] = 0;
            }
        }
        //将手牌信息分配到胡牌数组中
        foreach ( $card_array as $key => $value ){
            $card_huxi[ $value ]++;
        }
        //遍历牌组；如果有三个的；需要去除；然后把息增加到底息上
        $kan_length = 0;
        foreach ( $card_huxi as $key => $value ) {
            if( $value == 3 ){
                $card_huxi[$key] = 0;//设置该牌数为0，并增加底息
                $kanxi = $key <= 10 ? 3 : 6;//1-10的坎为3胡息；11-20的坎为6胡息；
                $huxi  = $huxi + $kanxi;
                $kan_length = $kan_length + 3;
            }
        }
        //将基础牌加入到胡牌数组中
        foreach ( $card_huxi as $key => $value ) {
            if( $key == $card_number ){
                $card_huxi[$key]++;
            }
        }
        //牌数+1,+的1 就是摸进来的那个牌
        $card_length = count( $card_array ) + 1 - $kan_length;
        $isZiMoOrCardNumber = $isZiMoOrCardNumber == $card_number ? $card_number : -1;//是否自摸判断
        //默认为不能胡的状态
        self::$canHu          = false;//默认不能胡
        self::$huXi           = 0;//0胡息
        self::$temp_log_card  = $card_huxi;//临时变量，没什么用
        //本房间是否打1.5.10 - 判断是否存在2
        $mttype = $room_info['room_mtype'];
        if( strstr( $mttype  , "2" ) == true ){
            self::$is_1510 = true;
        }else{
            self::$is_1510 = false;
        }
        //执行胡的判断
        self::__CanHu( $huxi , $card_huxi , $card_length , $isZiMoOrCardNumber , array() );
        //返回胡的判断的结果
        return array( 'canHu' => self::$canHu , 'huXi' => self::$huXi  );
    }

    /**
     * 返回平胡的用户ID
     * @param $room_id
     * @param $input_uid
     * @param $card_number
     * @param $db_connect
     * @return bool
     */
    public static function __chkAllUser_returnHU_UID( $room_id , $input_uid , $card_number , $db_connect ){
        $room_info = $db_connect->select('*')->from('tt_room')->where("room_id= '". $room_id ."' ")->row();//取出房间信息
        $card_info = $db_connect->select('*')->from('tt_room_card')->where("jid = '". $room_info['room_js'] ."' and rid= '". $room_id ."' ")->orderByASC( array('id') )->query();
        $hu_uid     = 0;
        foreach ( $card_info as $key => $value ){
            if( $value['uid'] != $input_uid ){
                $default_huxi = PHZ_Tools::__get_user_xpAndKanzi_Huxi( $room_id , $value['uid'] );
                $canHu = self::__isCan_Hu_Pai($default_huxi, $value['sp'], $card_number, -1 , $room_info );
                if( $canHu['canHu'] == true ){
                    $hu_uid = $value['uid'];
                    break;
                }
            }
        }
        return $hu_uid;
    }

    /**
     * 所有用户判胡接入；这里是发生在用户"手打牌"的情况下(这里只需要判断除自己外的其他三家即可) - 放炮胡
     * @param $room_id      房间ID
     * @param $input_uid    出牌人 - 其实也就是放炮人
     * @param $mode         模式（默认"hand"）
     * @param $card_number  牌号
     * @param $is_pao       是否有跑牌？
     * @param $pao_uid      跑牌人ID
     */
    public static function __chkAllUser_canHu( $room_id , $input_uid , $mode , $card_number , $db_connect , $is_pao = false , $pao_uid = 0 ){
        $room_info = $db_connect->select('*')->from('tt_room')->where("room_id= '". $room_id ."' ")->row();//取出房间信息
        $card_info = $db_connect->select('*')->from('tt_room_card')->where("jid = '". $room_info['room_js'] ."' and rid= '". $room_id ."' ")->orderByASC( array('id') )->query();
        $card_info = PHZ_Card::__cardInfoUserSort( $card_info , $input_uid );//按照出牌人的顺序进行整理
        $is_hu     = false;
        foreach ( $card_info as $key => $value ){
            if( $value['uid'] != $input_uid ){
                $default_huxi = PHZ_Tools::__get_user_xpAndKanzi_Huxi( $room_id , $value['uid'] );
                if( $is_pao == true && $value['uid'] == $pao_uid ){
                    $paiNumberArray = PHZ_Card::__cardSpGETPaoSP__AND_TEMP_CARD_NUMBER( $value['sp'] );//进行临时牌解析与查询
                    if( $paiNumberArray[0] != "" && $paiNumberArray[1] != 0 ){
                        if( $paiNumberArray[2] > 0 ){$default_huxi = $default_huxi + $paiNumberArray[2];}//BUG:跑胡后,手中被去掉的息没有累计进去
                        $canHu = self::__isCan_Hu_Pai($default_huxi, $paiNumberArray[0] , $paiNumberArray[1] , -1 , $room_info );//如果当前是跑牌胡，那么则抽取一个牌作为基础牌
                    }else{
                        $canHu['canHu'] = false;
                    }
                }else {
                    $canHu = self::__isCan_Hu_Pai($default_huxi, $value['sp'], $card_number, -1 , $room_info );
                }
                if( $canHu['canHu'] == true ){
                    $is_hu = true;
                    //本局计分
                    PHZ_Scoring::__game_Single_END( $room_info , $canHu['huXi'] , $value['uid'] , $input_uid , $card_number , 0 , $db_connect );
                    //结束判断
                    break;
                }
            }
        }
        return $is_hu;
    }

}